Android开启热点后作为路由器,获取AP端IP地址 您所在的位置:网站首页 热点 IP地址 Android开启热点后作为路由器,获取AP端IP地址

Android开启热点后作为路由器,获取AP端IP地址

2023-09-20 07:49| 来源: 网络整理| 查看: 265

最近在做类似面对面通信,需要一台手机作为AP端开启热点,另一台手机作为STA端连接热点,然后AP端告诉STA端它的IP地址,进行socket通信。 手机在联网时,就会被分配一个IP地址,它在开启热点时,它本身作为一个“路由器”也会生成一个IP地址,我们需要的就是后面这个IP地址,目前论坛上关于手机IP地址的帖子都是获取手机被分配的IP地址。我在解决这个问题时参考了蓝牙的配置IP地址,函数是configureBtIface(),在/frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java里。可以看到它也是先获取然后配置,参考这个,我写了获取热点IP地址的函数。 代码链接

private String configureBtIface(boolean enable, String iface) { Log.i(TAG, "configureBtIface: " + iface + " enable: " + enable); IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE); String[] bluetoothRegexs = cm.getTetherableBluetoothRegexs(); InterfaceConfiguration ifcg = null; String address = null; try { ifcg = service.getInterfaceConfig(iface); if (ifcg != null) { InetAddress addr = null; LinkAddress linkAddr = ifcg.getLinkAddress(); if (linkAddr == null || (addr = linkAddr.getAddress()) == null || addr.equals( NetworkUtils.numericToInetAddress("0.0.0.0")) || addr.equals( NetworkUtils.numericToInetAddress("::0"))) { address = BLUETOOTH_IFACE_ADDR_START; addr = NetworkUtils.numericToInetAddress(address); } ifcg.setLinkAddress(new LinkAddress(addr, BLUETOOTH_PREFIX_LENGTH)); if (enable) { ifcg.setInterfaceUp(); } else { ifcg.setInterfaceDown(); } ifcg.clearFlag("running"); service.setInterfaceConfig(iface, ifcg); if (enable) { int tetherStatus = cm.tether(iface); if (tetherStatus != ConnectivityManager.TETHER_ERROR_NO_ERROR) { Log.e(TAG, "Error tethering " + iface + " tetherStatus: " + tetherStatus); return null; } } else { int untetherStatus = cm.untether(iface); Log.i(TAG, "Untethered: " + iface + " untetherStatus: " + untetherStatus); } } } return address; }

下面getIpAddress()就是我写的开启热点以后获取AP端IP地址的函数,主要就是把蓝牙那边的参数改成了wlan0,就ok了。经过测试,log打出来的IP地址和手机执行ifconfig里wlan0里面的IP地址一模一样。当然,这个IP地址每次打开热点都是不一样的。在Android8.0以及之前这个IP地址是固定的,好像是"192.168.43.1"。9.0以后随机分配,可能是为了安全吧。

private String getIpAddress() { IBinder b = ServiceManager.getService(Context.NETWORKMANAGEMENT_SERVICE); INetworkManagementService service = INetworkManagementService.Stub.asInterface(b); InterfaceConfiguration ifcg = null; String address = null; try { ifcg = service.getInterfaceConfig("wlan0"); if (ifcg != null) { LinkAddress linkAddr = ifcg.getLinkAddress(); Log.d("test" , "linkAddr" + linkAddr.toString()); if (linkAddr != null) { InetAddress Inetaddr = linkAddr.getAddress(); Log.d("test" , "Inetaddr" + Inetaddr.toString()); if (Inetaddr != null) { address = Inetaddr.getHostAddress(); if (address != null) { Log.d("test" , "address " + address.toString()); } } } } } catch (Exception e) { Log.e("test", "Error configuring interface :" + e); return null; } return address; }

这里贴上Android9.0上开启热点时分配IP地址(ipv4)的代码:/frameworks/base/services/core/java/com/android/server/connectivity/tethering/TetherInterfaceStateMachine.java里的configureIPv4()函数。 代码链接

private boolean configureIPv4(boolean enabled) { if (VDBG) Log.d(TAG, "configureIPv4(" + enabled + ")"); // TODO: Replace this hard-coded information with dynamically selected // config passed down to us by a higher layer IP-coordinating element. String ipAsString = null; int prefixLen = 0; if (mInterfaceType == ConnectivityManager.TETHERING_USB) { ipAsString = USB_NEAR_IFACE_ADDR; prefixLen = USB_PREFIX_LENGTH; } else if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) { ipAsString = getRandomWifiIPv4Address(); prefixLen = WIFI_HOST_IFACE_PREFIX_LENGTH; } else { // Nothing to do, BT does this elsewhere. return true; } final LinkAddress linkAddr; try { final InterfaceConfiguration ifcg = mNMService.getInterfaceConfig(mIfaceName); if (ifcg == null) { mLog.e("Received null interface config"); return false; } InetAddress addr = NetworkUtils.numericToInetAddress(ipAsString); linkAddr = new LinkAddress(addr, prefixLen); ifcg.setLinkAddress(linkAddr); if (mInterfaceType == ConnectivityManager.TETHERING_WIFI) { // The WiFi stack has ownership of the interface up/down state. // It is unclear whether the Bluetooth or USB stacks will manage their own // state. ifcg.ignoreInterfaceUpDownStatus(); } else { if (enabled) { ifcg.setInterfaceUp(); } else { ifcg.setInterfaceDown(); } } ifcg.clearFlag("running"); mNMService.setInterfaceConfig(mIfaceName, ifcg); } catch (Exception e) { mLog.e("Error configuring interface " + e); return false; } // Directly-connected route. final RouteInfo route = new RouteInfo(linkAddr); if (enabled) { mLinkProperties.addLinkAddress(linkAddr); mLinkProperties.addRoute(route); } else { mLinkProperties.removeLinkAddress(linkAddr); mLinkProperties.removeRoute(route); } return true; }

关注公众号,获取更多开发必备知识 在这里插入图片描述



【本文地址】

公司简介

联系我们

今日新闻

    推荐新闻

    专题文章
      CopyRight 2018-2019 实验室设备网 版权所有